<template>
  <div>
    <el-dialog
      :title="dialogTitle"
      :visible.sync="visible"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :before-close="close"
      lock-scroll
      custom-class="crud-dialog large"
      :append-to-body="false"
      :destroy-on-close="!visible"
    >
      <div v-loading="loading" class="video-panel">
        <!--@click.prevent解决全屏时，点击video会暂停的问题-->
        <!--controlslist="nodownload" disablePictureInPicture 解决Microsoft Edge浏览器出现下载和画中画等更多控件的问题-->
        <video ref="video" class="video" autoplay muted controlslist="nodownload" disablePictureInPicture @dblclick="doFullScreen" @click.prevent>
        </video>
        <div v-show="isRecorderLongPress" class="recwave"></div>
        <div class="controls">
          <span v-if="screenShot && !loading" class="shotcut-btn" @click="handleScreenshot">
            截屏
          </span>
          <span v-if="mutedControl && !loading" class="iconfont icon-audio audio-btn" :class="{'audio-btn-muted':muted}" @click="switchMuted"></span>

          <span v-if="!video.timeRange && !loading && recorderOn" title="鼠标长按发送语音制止(时长在1分钟以内)" type="primary" class="recorder-btn" @mousedown="recorderMouseDown" @mouseup="recorderMouseUp" @mouseout="recorderMouseUp">
            长按语音制止
          </span>

          <canvas v-show="false" ref="canvasRef"></canvas>
        </div>

      </div>

    </el-dialog>
  </div>
</template>

<script>
import {VideoFlv} from "@haiking/haiking-jstool";
import Recorder from 'recorder-core'
import 'recorder-core/src/engine/pcm'

import 'recorder-core/src/extensions/lib.fft.js'

import 'recorder-core/src/extensions/frequency.histogram.view.js'
import screenfull from 'screenfull'
import {
  startRealtimeVideoStream,
  stopRealtimeVideoStream,
  keepRealtimeVideoStream,
  sendRecorderToVideo
} from "@/api/video";
export default {
  props: {
    screenShot: {
      type: Boolean,
      default: false,
    },
    mutedControl: {
      type: Boolean,
      default: true,
    },
    recorderOn: {
      type: Boolean,
      default: false,
    }
  },
  data() {
    return {
      visible: false,
      video: {},
      keepInterval: undefined,
      isStreamLive: false,
      loading: false,
      dialogTitle: "",
      muted: true,
      recordLongPressTimeout: undefined,
      isRecorderLongPress: false,
      recorderControl: undefined,
      recorderOpened: false,
      wave: undefined
    }
  },
  mounted() {
    // this.initVideo();
    this.initRecorder();
  },

  methods: {
    initRecorder() {
      this.recorderControl = Recorder({ // 本配置参数请参考下面的文档，有详细介绍
          type: "pcm",// 格式，pcm mp3 wav
          // sampleRate: 16000,
          sampleRate: 8000, // 采样率hz
          bitRate: 16, // 比特率kbps，
          onProcess: (buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd) => {
            // 可视化图形绘制
            this.wave && this.wave.input(buffers[buffers.length - 1],powerLevel,bufferSampleRate);
          }
      });
    },
    open(videoInfo) {
      this.video = videoInfo;
      if (this.video.timeRange) {
        this.dialogTitle = "历史回放"
      } else {
        this.dialogTitle = "实时监控"
      }
      this.visible = true;
      this.$nextTick(() => {
        this.initVideo(this.video);
      })
    },
    close() {
      this.visible = false;
      this.$emit("close");
      if (this.video && this.isStreamLive) {
        this.stopVideoStream(this.video);
        // 关闭录音资源
        this.closeSystemRecorder()
      }
    },
    // 全屏
    doFullScreen() {
        const videoElem = this.$refs.video
        if (screenfull.isEnabled) {
            screenfull.request(videoElem)
        }
    },
    // 停止直播流
    stopVideoStream(video) {
      this.clearKeepInterval();
      // 暂时关闭直播流停止的接口调用，后端已经修改为自行处理关闭

      // 历史回放流时，调用停止接口
      if (this.video.timeRange) {
        stopRealtimeVideoStream({
          cameraId: video.id,
          // clientType: 1,
          // platform: "sturgeon",
          // streamQuality: "01",
          channelId: video.channel,
          streamType: video.timeRange ? 2 : 1,// 历史流2，实时流1
          shipCatCode: video.shipcatCode,
          startTime: video.timeRange && video.timeRange[0],
          endTime: video.timeRange && video.timeRange[1]
        })
      }

      this.isStreamLive = false;
    },
    // 清除心跳保活定时器
    clearKeepInterval() {
      if (this.keepInterval) {
        clearInterval(this.keepInterval);
      }
      this.keepInterval = undefined;
    },
    // 开启心跳发送，保活
    startKeepVideo(video) {
      this.clearKeepInterval();
      this.keepInterval = setInterval(() => {
        keepRealtimeVideoStream({
          cameraId: video.id,
          // clientType: 1,
          // platform: "sturgeon",
          // streamQuality: "01",
          channelId: video.channel,
          streamType: video.timeRange ? 2 : 1,// 历史流2，实时流1
          shipCatCode: video.shipcatCode,
          startTime: video.timeRange && video.timeRange[0],
          endTime: video.timeRange && video.timeRange[1]
        })
      }, 60000);
    },
    async initVideo(video) {
      this.loading = true;
      const startResult = await startRealtimeVideoStream({
        cameraId: video.id,
        clientType: 1,
        platform: "sturgeon",
        streamQuality: video.cameraType == "1" ? "01" : "0",// 大华的streamQuality为0，海康的为01
        channelId: video.channel,
        streamType: video.timeRange ? 2 : 1,// 历史流2，实时流1
        shipCatCode: video.shipcatCode,
        cameraType: video.cameraType,
        startTime: video.timeRange && video.timeRange[0],
        endTime: video.timeRange && video.timeRange[1]
      });
      this.loading = false;

      if (!startResult.result || !startResult.result.streamUrl) {
        return;
      }
      // const startResult = {
      //   result: {
      //     streamUrl: "http://192.168.3.38/live?port=1935&app=live&stream=room"
      //   }
      // }
      const videoElement = this.$refs.video;
      this.videoFlv = new VideoFlv(
        {
          type: "flv", // 如果是直播流需要设置这个值为 true
          isLive: true, // 拉流示例地址，stream参数一定要和推流时所设置的流密钥一致，app是推流的uri
          // url: "http://192.168.3.195/live?port=1935&app=live&stream=room",
          // url: "http://192.168.3.144/live?port=1935&app=live&stream=201",
          // url: "http://192.168.3.195/hls/room.m3u8",
          // url: "http://192.168.1.221/live?port=1935&app=live&stream=room",
          url: startResult.result.streamUrl
        },
        {
          videoElement: videoElement,
          enableWorker: false, // 启用分离的线程进行转换
          enableStashBuffer: false, // 关闭IO隐藏缓冲区
          // stashInitialSize: 128, // 减少首帧显示等待时长
          // headers: {
          //   Authorization: this.$auth.getToken();,
          // },
        }
      );
      this.isStreamLive = true;
      this.startKeepVideo(video);
    },
    // 切换静音
    switchMuted() {
      this.muted = !this.muted;
      if (this.$refs.video) {
        this.$refs.video.muted = this.muted;
      }
    },

    // 截图
    handleScreenshot() {
      // 获取video节点
      const video = this.$refs.video;
      // 创建canvas节点
      const canvas = this.$refs.canvasRef;

      // 获取 video 宽高
      const width = video.clientWidth;
      canvas.width = width;

      const height = video.clientHeight;
      canvas.height = height;

      const ctx = canvas.getContext('2d');
      // video写入到canvas
      ctx.drawImage(video, 0, 0, width, height);

      // 生成截图地址
      const imgUrl = canvas.toDataURL('image/png');

      // 下载截图
      this.downFile(imgUrl, `${this.video.id ? this.video.id : "截图"}.png`);
    },

    // 下载截图
    downFile(data, fileName) {
      const link = document.createElement('a');

      link.href = data;
      link.download = fileName;
      link.click();

      // 释放内存
      window.URL.revokeObjectURL(link.href);
    },

    // 打开系统录制麦克风
    openSystemRecorder() {
      console.log("open!")
      return new Promise((resolve, reject) => {
        this.recorderControl && this.recorderControl.open(() => {
          resolve({success: true})
        },(msg,isUserNotAllow) => {
          // console.log(isUserNotAllow,msg)
          reject({msg,isUserNotAllow})
        })
      })
    },
    // 关闭系统录制麦克风
    closeSystemRecorder() {
      this.recorderControl && this.recorderControl.close();
      this.recorderOpened = false;
    },
    // 停止录制
    stopRecorder() {
      return new Promise((resolve, reject) => {
        this.recorderControl && this.recorderControl.stop((blob,duration) => {
          resolve({blob,duration})
        },(msg) => {
          // console.log(isUserNotAllow,msg)
          reject({msg})
        })
      })
    },

    recorderMouseDown() {
      this.isRecorderLongPress = false
      this.recordLongPressTimeout = setTimeout(() => {
        if (this.isRecorderLongPress == false) {
          this.isRecorderLongPress = true
          // 录制控件未打开
          if (this.recorderControl && Recorder.IsOpen()) {
            this.recorderControl && this.recorderControl.start();
          } else {
            this.openSystemRecorder().then(res => {
              if (res.success) {
                this.wave = Recorder.FrequencyHistogramView({elem: ".recwave"});
                this.recorderOpened = true
                this.recorderControl && this.recorderControl.start();
              }
            }).catch(err => {
              console.error('出错',err.msg)
            })
          }
        }
      }, 500) // 500毫秒后未松开就认为是长按
    },
    recorderMouseUp() {
      // 长按处理
      if (this.isRecorderLongPress == true) {
        this.isRecorderLongPress = false

        this.recordLongPressTimeout = undefined;
        if (this.recorderControl && Recorder.IsOpen()) {
          this.stopRecorder().then(res => {
            const secondNum = res.duration / 1000
            if (secondNum > 60) {
              this.$message.warning("语音时长需要控制在1分钟以内")
              return;
            } else if (secondNum < 2) {
              this.$message.warning("语音时长太短，请重新录制")
              return;
            }
            const formData = new FormData()
            formData.append('pcm', res.blob)
            // formData.append('cameraId',this.video.id)
            // formData.append('channelId',this.video.channel)//
            formData.append('shipCatCode',this.video.shipcatCode)// 船锚code
            sendRecorderToVideo(formData)
          }).catch(err => {
            console.error('出错',err.msg)
          })
        }
      } else {
        // console.log("单击 click")
      }

      // 清空Timeout
      this.recordLongPressTimeout && clearTimeout(this.recordLongPressTimeout);
    }
  },
}
</script>
<style lang="scss" scoped>
// /* 隐藏video 全屏按钮 */
// .video::-webkit-media-controls-fullscreen-button {
//     display: none;
// }
// /* 隐藏video 播放按钮 */
// .video::-webkit-media-controls-play-button {
//     display: none;
// }
// /* 隐藏video 进度条 */
// .video::-webkit-media-controls-timeline {
//     display: none;
// }
// /* 隐藏video 观看的当前时间 */
// .video::-webkit-media-controls-current-time-display{
//     display: none;
// }
// /* 隐藏video 剩余时间 */
// .video::-webkit-media-controls-time-remaining-display {
//     display: none;
// }
// /* 隐藏video 音量按钮 */
// // .video::-webkit-media-controls-mute-button {
// //     display: none;
// // }
// .video::-webkit-media-controls-toggle-closed-captions-button {
//     display: none;
// }
// /* 隐藏video 音量的控制条 */
// .video::-webkit-media-controls-volume-slider {
//     display: none;
// }
// /* 隐藏video 所有控件 */
// .video::-webkit-media-controls-enclosure{
//     display: none;
// }

video::-webkit-media-controls,
    video::-moz-media-controls,
    video::-webkit-media-controls-enclosure{
    display:none !important;
}

video::-webkit-media-controls-panel,
video::-webkit-media-controls-panel-container,
video::-webkit-media-controls-start-playback-button {
    display:none !important;
    -webkit-appearance: none;
}

// //播放按钮
// video::-webkit-media-controls-play-button {
//     display: none;
// }
// //进度条
// video::-webkit-media-controls-timeline {
//     display: none;
// }
// //观看的当前时间
// video::-webkit-media-controls-current-time-display{
//     display: none;
// }
// //剩余时间
// video::-webkit-media-controls-time-remaining-display {
//     display: none;
// }

::v-deep .el-dialog__body{
  padding:3px;
  border-radius: 0;
}
.video-panel{
  width:100%;
  height:100%;
  .controls{
    position:absolute;
    display:flex;
    justify-content:space-between;
    align-items:center;
    bottom:15px;
    right:10px;
    span{
      margin-left:5px;
      line-height: normal;
      padding: 5px;
      border-radius: 6px;
      cursor: pointer;
      background-color: #040404d9;
      color: #ffffff;
    }
    .audio-btn{
      color:#3accfd;

      &:before{
        font-size:19px;
      }
    }
    .audio-btn-muted{
      color:gray;

    }
    .recorder-btn{
      //padding: 7px 10px;
      padding: 5px 10px;
      font-size: 14px;
    }

  }
  .recwave{
    height: 100px;
    width: 300px;
    position: absolute;
    bottom: 46px;
    right: 10px;
    border: 1px solid black;
    border-radius: 5px;
    background: #000000ad;

  }
}
.video{
  width:100%;
}
</style>

